package com.pz.chat.netty_ws;

import com.pz.chat.netty_ws.handlers.WebSocketServerHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {

    @Value("${netty.websocket.server.path}")
    private String wsPath;

    @Autowired
    private WebSocketServerHandler webSocketHandler;
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        log.info("================== the start report of netty ==================");
        log.info("info：there is a client connect to server...");
        log.info("IP:{}", socketChannel.remoteAddress().getAddress());
        log.info("Port:{}", socketChannel.remoteAddress().getPort());
        log.info("channelID:{}", socketChannel.id().toString());
        log.info("================== the end report of netty ==================");

        ChannelPipeline pipeline = socketChannel.pipeline();
        // ws基于Http协议，需要使用http的编码和解码器
        pipeline.addLast(new HttpServerCodec());
        // 最大数据长度（http数据传输是分段的，HttpObjectAggregator可以聚合这些分段数据）
        pipeline.addLast(new HttpObjectAggregator(65536));
        // 添加接收websocket请求的url匹配路径,当客户端传递比较大的对象时，maxFrameSize参数的值需要调大
        pipeline.addLast(new WebSocketServerProtocolHandler(wsPath, null, true, 65536*10));
        // 10秒内收不到消息强制断开连接
        // pipeline.addLast(new ReadTimeoutHandler(10, TimeUnit.SECONDS));
        pipeline.addLast(webSocketHandler);
        // 以块方式写
        pipeline.addLast(new ChunkedWriteHandler());
        // 聚合 websocket 的数据帧，因为客户端可能分段向服务器端发送数据
        pipeline.addLast(new WebSocketFrameAggregator(10 * 1024 * 1024));
    }
}
